Component design & architecture

The overall architecture could be microservices-based with heavy usage of the publisher-subscriber pattern, involving a queuing technology like Kafka, RabbitMQ, ActiveMQ, Amazon SNS, or Amazon MQ. Each microservice can talk with another using this model of publishing a message and subscribing to channels or topics. This mechanism de-couples services from each other in the best possible way.

Consequently, microservice A doesn’t need to know the endpoint of microservice B when it publishes a message to the queue. The publisher doesn’t need to know the consumers (subscribers) of its published messages. Similarly, the subscriber doesn’t know about the source of the message, i.e., the publisher. The Pub/Sub system becomes a broker and serves as a contract between all the involved parties.

Also, it is imperative that each microservice interacts with its own database and doesn’t share with anyone else. This approach is motivated by the database-per-service paradigm. Microservice A doesn’t have direct access to microservice B's database as they are separated and individually owned.

As described earlier, the data model proposes the idea of just one big fat schema containing every possible table.

Microservices architecture is opposed to this concept. Functional partitioning is required to grant the ownership of each significant table or group of tables to one microservice. That discussion is out of scope here. However, we could choose a mix of relational and non-relational databases for our data storage requirements, which is where functional partitioning becomes more pertinent. The astute reader could take up, as an exercise, the ways the given schema could be partitioned to fit into the microservices architecture.

Various components of the system#

UI client#

The application will be accessible via mobile, web, tablets, etc. Based on the actor, the interfaces presented will be different or a combination of many. So, individual interfaces/pages will talk to the respective service for parts of the functionality. For example, the search can be performed by the Restaurant Search Service, and orders can be handled by the Ordering Service, and so on.

Primarily, there will be four versions of the interface for the four actors: customer, restaurant, DoorDasher and admin.

Search ecosystem#

The most important and coveted functionality that has to be provided by the system is the capability of searching on menu items, cuisines, restaurants, among other things. In the food ordering journey, this functionality will be the entry point for all the customers, unless they already have a favorite restaurant in their preferences. Thus, a personalized discovery and search experience based on a customer’s past search and order history must be provided. As is apparent, this particular part of the entire system will be read-heavy.

We can think of leveraging popular off-the-shelf search offerings from the market, such as Elasticsearch or Apache Solr, for quick lookup as per user search parameters. These technologies are open-source, distributed, and based on Apache Lucene and have their own strengths and weaknesses.

We will need to have a queue in place to process asynchronous updates to the search cluster. When the Restaurant Profile Service (see below) creates/updates a restaurant/menu data by performing CRUD operations on the database, it can also post an event to the queue. This event could be any of the CRUD. We need a data indexer that listens to the queue for such events. The data indexer then picks up the event, runs a query against the database to formulate a document as per the correct format, and posts the data into the search cluster. We also need to have a Restaurant Search Service that executes queries on the search cluster based on user inputs and returns the result to be displayed on the user interface.

Elasticsearch has a Geo-distance query, which can be leveraged to return all the restaurants/menus that the user is searching for based on a defined radius from the user’s location. This essentially means that users will be shown only those restaurants that are reachable from their addresses. Similarly, Apache Solr also has Spatial Search, which caters to the use case of geographic search. As such, Elasticsearch is very fast in retrieving results and can be directly queried. To further reduce latency and improve user experience, we should use a cache working alongside the Restaurant Search Service. More on caching in upcoming lessons.

The search ecosystem will look like the diagram below:

Search ecosystem

Ordering service#

This service will manage the menu selection, shopping cart management, and placement of food orders. It will process the payment using an External Payment Gateway and will save the result into an orders database. Because order placement is transactional in nature, the best idea is to use a relational database.

Customers will be able to get the full receipt of their order and other details using this service. They can also cancel the order and view their past order histories.

Order fulfilment service#

A Few high-level functionalities that this service will handle are listed below.

  • The restaurant accepts the order (using the client app).
  • Notifies the customer of any delay or change in the order if necessary (using the Notification Service).
  • Customers can check the status of their orders.
  • DoorDashers can check if the order is ready to be picked up. They can also view the details of the order they are picking up/delivering.
  • Notifies the DoorDasher when an order is ready to be picked up.

User profile management & preferences service#

The actors in the system, namely, customers, restaurant staff, DoorDashers and system admin, will need a way to create their profile with personal information, contact, address, and will be assigned a role based on their profile. Individual actors will also have preferences based on their role. For example, customers may have set preferences for selecting from a fixed set of restaurants or zip codes or cuisines. Doordashers might have a preference for delivering only within their specific area codes, or choice of restaurants, etc. Similarly, actors will also have their preferred method of ordering or getting paid. Notification preferences of actors will also vary. This service will manage the profiles and preferences of all such actors across the board.

DoorDasher dispatch service#

This service will be used to accomplish use-cases relating to a DoorDasher. DoorDashers will be able to:

  • view pick-up orders from a list that they can accept;
  • accept an order;
  • view past orders that they have accepted;
  • view customer information from the order in case they need to communicate with them about the delivery, or inform the restaurant about any problem that prevents them from picking up or delivering the food.

Restaurant profile service#

This service will be managing the data related to restaurants, menus, offerings, etc. A restaurant or business can:

  • Onboard
  • Update/Delete their profile
  • Create/Update/See/Delete menus, dishes etc.
  • Upload images of their restaurants or dishes/menus into an object storage service
  • View their financial details based on past orders etc.
  • Setup a payment method for money transfers

External payment gateway#

This component can interface with popular payment gateways like Amazon Payments, We Pay, PayPal, ApplePay, or individual Credit Card providers like Amex, Visa, Mastercard, etc. The order service will interact with this component to ensure the payment is made at the time of confirmation of order. The interaction should be synchronous in nature.

Notification service#

This service is responsible for delivering notifications to every actor within the system. The notifications should be sent out to individual actors according to the preferences they have set for receiving them. Some actors might prefer push notifications while others might receive text or emails. This service is supposed to abstract out the medium in which notifications are being sent. This means the underlying interactions with the mobile carrier, email service providers, etc. will be abstracted. Actors could also receive in-app notifications. The service is responsible to notify:

  • the customer about various stages of the order. Examples include notifications about successful order placement, acceptance of order by the restaurant, or the dispatch of the order;
  • the restaurant that an order is placed, or a DoorDasher is assigned to the order, or that the DoorDasher is on their way to pick up the order;
  • the DoorDasher that orders are waiting in their queue for acceptance, or that the order is ready to be picked up, or that the order they have accepted is being delayed, etc.

The complete component design with all the services will look like this.

Component design of the system

Test your knowledge of what you’ve learnt in this lesson.

1

Which payment procedure will we be using to process the payments?

A)

Internal Payment Method

B)

External Payment Gateway

C)

Cash on Delivery

Question 1 of 20 attempted
Creating Data Model, Managing Data Storage & Data Partitioning
Learn Order Fulfilment Workflow, System APIs & Security
Mark as Completed